package com.vip.iot.mina;

import com.vip.common.util.HexBinUtils;
import com.vip.iot.util.PropertiesUtils;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.net.InetSocketAddress;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Mina客户端
 *
 * @author wgb
 * @date 2020/6/19 17:27
 */
public class MinaClient extends IoHandlerAdapter {
    private IoConnector connector;
    private static IoSession session;
    private static Lock lock = new ReentrantLock();

    public MinaClient() {
        connector = new NioSocketConnector();
        connector.setHandler(this);
        ConnectFuture connFuture = connector.connect(new InetSocketAddress("localhost", Integer.parseInt(PropertiesUtils.getYmlFileProperty("application.yml", "mina.port").toString())));
        connFuture.awaitUninterruptibly();
        session = connFuture.getSession();
        System.out.println("TCP 客户端启动");
    }

    /**
     * 创建客户端并且发送信息
     */
    public static void createClientAndSendMessage() {
        lock.lock();
        MinaClient client = new MinaClient();
        byte[] bts = new byte[20];
        for (int i = 0; i < 20; i++) {
            // 将数字转换为字节
            bts[i] = (byte) i;
        }
        IoBuffer buffer = IoBuffer.allocate(20);
        // 自动扩容
        buffer.setAutoExpand(true);
        // 自动收缩
        buffer.setAutoShrink(true);
        buffer.put(bts);
        buffer.flip();
        session.write(buffer);
        // 关闭会话，待所有线程处理结束后
        client.connector.dispose(true);
        lock.unlock();
    }

    @Override
    public void messageReceived(IoSession iosession, Object message) {
        IoBuffer bbuf = (IoBuffer) message;
        byte[] byten = new byte[bbuf.limit()];
        bbuf.get(byten, bbuf.position(), bbuf.limit());
        // 将收到的消息转换为
        System.out.println("客户端收到消息" + HexBinUtils.byte2HexStr(byten, byten.length));
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        super.exceptionCaught(session, cause);
    }

    @Override
    public void messageSent(IoSession iosession, Object obj) throws Exception {
        super.messageSent(iosession, obj);
    }

    @Override
    public void sessionClosed(IoSession iosession) throws Exception {
        super.sessionClosed(iosession);
    }

    @Override
    public void sessionCreated(IoSession iosession) throws Exception {
        super.sessionCreated(iosession);
    }

    @Override
    public void sessionIdle(IoSession iosession, IdleStatus idlestatus) throws Exception {
        super.sessionIdle(iosession, idlestatus);
    }

    @Override
    public void sessionOpened(IoSession iosession) throws Exception {
        super.sessionOpened(iosession);
    }

    public static void main(String[] args) {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20, 10, TimeUnit.SECONDS
              , new ArrayBlockingQueue<>(10), new ThreadPoolExecutor.DiscardOldestPolicy());
        for (int i = 0; i < 500; i++) {
            threadPool.execute(() -> new Thread(() -> createClientAndSendMessage()).start());
        }
    }
}
